package models

import (
	"fmt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"strings"
)

// 采集池 和机器的关系
// 1对多 机器只能属于1个采集池
// 新建采集池 就需要填入ip
// 主配置文件池
// 采集池 和告警触发 共用这个池子
type MonitorScrapePool struct {
	Model        // 不用每次写ID 和 createAt了
	Name  string `json:"name" validate:"required,min=1,max=50" gorm:"uniqueIndex;type:varchar(100);comment:采集池名称，支持使用通配符*进行模糊搜索" `

	// 选择多个采集器 实例
	PrometheusInstances StringArray `json:"prometheusInstances" `

	// D:\nyy_work\go_path\src\github.com\prometheus\prometheus\config\config.go
	// 下面是global段
	UserID         uint
	ScrapeInterval int `json:"scrapeInterval" gorm:"default:30;comment: 采集间隔"`
	ScrapeTimeout  int `json:"scrapeTimeout" gorm:"default:10;comment: 采集超时时间"`

	ExternalLabels StringArray `json:"externalLabels" gorm:"comment: remote_write的时候添加的 标签组 key=v ,scrape_ip=1.1.1.1 "`

	// 告警段 是否支持告警 =1 就支持 =2就不支持
	SupportAlert    int    `json:"supportAlert" gorm:"comment:是否支持告警 =1 就支持 =2就不支持"`   //用户是否被冻结 1正常 2冻结
	SupportRecord   int    `json:"supportRecord" gorm:"comment:是否支持预聚合 =1 就支持 =2就不支持"` //用户是否被冻结 1正常 2冻结
	RemoteReadUrl   string `json:"remoteReadUrl"  gorm:"comment: 远程读取的地址"`
	AlertManagerUrl string `json:"alertManagerUrl"  gorm:"comment: alert的地址"`
	RuleFilePath    string `json:"ruleFilePath"  gorm:"comment: rule文件路径"`
	RecordFilePath  string `json:"recordFilePath"  gorm:"comment: record文件路径"`

	// remoteWrite段
	RemoteWriteUrl       string `json:"remoteWriteUrl" gorm:"comment: 远程写入的地址"`
	RemoteTimeoutSeconds int    `json:"remoteTimeoutSeconds" gorm:"default:5;comment: 远程写入的超时时间"`

	// ExternalLabels \n join的结果
	ExternalLabelsFront string `json:"externalLabelsFront" gorm:"-"`
	Key                 string `json:"key" gorm:"-"` //给前端表格
	CreateUserName      string `json:"createUserName" gorm:"-"`
}

func (obj *MonitorScrapePool) Create() error {
	return Db.Create(obj).Error

}
func (obj *MonitorScrapePool) DeleteOne() error {

	return Db.Select(clause.Associations).Unscoped().Delete(obj).Error

}

func (obj *MonitorScrapePool) CreateOne() error {
	return Db.Create(obj).Error

}

func (obj *MonitorScrapePool) UpdateOne() error {
	return Db.Where("id = ?", obj.ID).Updates(obj).Error

}

// 要求新增和更新的时候 ip不能重复
func (obj *MonitorScrapePool) CheckIpExists() bool {
	all, err := GetMonitorScrapePoolAll()
	if err != nil {
		return true
	}
	ipMap := map[string]string{}
	for _, p := range all {
		p := p
		if p.Name == obj.Name {
			// 跳过自己
			continue
		}
		for _, ip := range p.PrometheusInstances {
			ipMap[ip] = ip
		}

	}

	for _, ip := range obj.PrometheusInstances {
		_, ok := ipMap[ip]
		if ok {
			return true
		}
	}
	return false
}

// 0值替换
func (obj *MonitorScrapePool) FillDefaultData() {
	if obj.ScrapeTimeout == 0 {
		obj.ScrapeTimeout = 10
	}
	if obj.ScrapeInterval == 0 {
		obj.ScrapeInterval = 30
	}
	if obj.RemoteTimeoutSeconds == 0 {
		obj.RemoteTimeoutSeconds = 5
	}

}

func (obj *MonitorScrapePool) FillFrontAllData() {
	dbUser, _ := GetUserById(int(obj.UserID))
	if dbUser != nil {
		obj.CreateUserName = dbUser.Username
	}

	obj.ExternalLabelsFront = strings.Join(obj.ExternalLabels, "\n")
	obj.Key = fmt.Sprintf("%d", obj.ID)

}
func GetMonitorScrapePoolAll() (objs []*MonitorScrapePool, err error) {
	err = Db.Find(&objs).Error
	return
}

func GetMonitorScrapePoolSupportAlertAll() (objs []*MonitorScrapePool, err error) {
	err = Db.Where("support_alert = 1").Find(&objs).Error
	return
}

func GetMonitorScrapePoolSupportRecordAll() (objs []*MonitorScrapePool, err error) {
	err = Db.Where("support_record = 1").Find(&objs).Error
	return
}

func GetMonitorScrapePoolByLevel(level int) (objs []*MonitorScrapePool, err error) {
	err = Db.Where("level = ?", level).Preload("OpsAdmins").Find(&objs).Error
	return
}

// select * from ecs where
func GetMonitorScrapePoolByIdsWithLimitOffset(ids []int, limit, offset int) (objs []*MonitorScrapePool, err error) {
	err = Db.Limit(limit).Offset(offset).Find(&objs, ids).Error
	return
}

func GetMonitorScrapePoolByInstanceId(instanceId string) (*MonitorScrapePool, error) {

	var dbObj MonitorScrapePool
	err := Db.Where("instance_id = ?", instanceId).First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("MonitorScrapePool不存在")
		}
		return nil, fmt.Errorf("数据库错误:%w", err)
	}
	return &dbObj, nil

}

func GetMonitorScrapePoolById(id int) (*MonitorScrapePool, error) {

	var dbObj MonitorScrapePool
	err := Db.Where("id = ?", id).First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("MonitorScrapePool不存在")
		}
		return nil, fmt.Errorf("数据库错误:%w", err)
	}
	return &dbObj, nil

}
